package com.blackline.auto.common;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;

import org.apache.log4j.Logger;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.google.common.io.Files;

/**
 * This class contains the common methods being used in Blackline automation project. <br>
 * !!!!Notice!!!!<br>
 * All the common methods in this file are of non-relationship with a web page.<br>
 * @author XBOSoft
 * @version Feb, 2013
 */
public class CommonMethods {
	private static Logger logger=Logger.getLogger(CommonMethods.class);
	/**
	 * Create a file and write some texts into it.
	 * @param fileNameWithPath The path and file name you want to create. For example "TestData/a.txt" or "C:/a.txt"
	 * @param textToInput The texts to be input into the created file.
	 * <br>Sample:
	 * createFile("TestData/Account.Import.txt", "4000	z2013022001 z2013022001"
	 */
	public static void createFile(String fileNameWithPath, String textToInput) {
		try {
			File f = new File(fileNameWithPath);
			if (f.exists()) {
				logger.info("File " + fileNameWithPath + " already exists. Will overwrite.");
			} else {
				logger.info("File " + fileNameWithPath	+ " does NOT exist. Will create.");
				f.createNewFile();// Create file.
				logger.info("Created file: " + fileNameWithPath);
			}
			BufferedReader reader = new BufferedReader(new FileReader(f));
			if (textToInput.length()<500)
			{
			logger.info("The texts to input is as the following:");
			logger.info(textToInput);
			}
			reader.close();

			BufferedWriter writer = new BufferedWriter(new FileWriter(f));
			writer.write(textToInput);
			logger.info("Has written the text into: " + fileNameWithPath);
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Delete a file
	 * @param fileNameWithPath The file to be deleted.
	 * @return true or false
	 */
	public static boolean deleteFile(String fileNameWithPath)
	{
	    boolean flag = false;   
	    File file = new File(fileNameWithPath);   
	    if (file.isFile() && file.exists()) {
	    	logger.info("Going to delete file: " + fileNameWithPath);
	        file.delete();   
	        flag = true;   
	    }
	    return flag;
	}
	
	/**
	 * Generate a string based on current time: 20110305-08-23-15
	 * @return A time string
	 */
	public static String dateString(){
		//Generate current time string, and write into Account.Import.txt later
		SimpleDateFormat sdf =new SimpleDateFormat("yyyyMMdd-kk-mm-ss");
		Date date = new Date();
		
		String dateString = sdf.format(date);
		logger.info("String of current time is: " + dateString);
		return dateString;
		
	}
	
	/**
	 * Get the text strings from Windows Clipboard
	 * @return strings
	 */
	public String getClipboardStrings()
	{
		String text = "";
		Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
		Transferable clipTf = cb.getContents(null); 
		if (clipTf != null) { 
            // Check whether it's Text type 
            if (clipTf.isDataFlavorSupported(DataFlavor.stringFlavor)) { 
                try { 
                    text = (String) clipTf.getTransferData(DataFlavor.stringFlavor); 
                } catch (Exception e) { 
                    e.printStackTrace(); 
                } 
            } 
        } 
		return text;
	}
	
	/**
	 * Get a line of strings which matches the "pattern" in specific file
	 * @param filePath The file path + the file name.
	 * @param pattern The pattern of the string to match
	 * @return String: the line of the string.<br>
	 * Sample:<br>
	 * 
	 */
	public String getStringLine(String filePath, String pattern) {
		File file = new File(filePath);
		List<String> list = new ArrayList<String>();
		String returnString = ""; 
		int numberOfWidgets = 0;
		try {
			BufferedReader br = new BufferedReader(new FileReader(file));
			String line = null;

			// Store data into list
			while ((line = br.readLine()) != null) {
				list.add(line);
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		for (int i = 0; i < list.size(); i++) {
			String s = (String) list.get(i);
			if (s.contains(pattern))
			{
				returnString = s;
				logger.info("Find a line: " + s);
			}
		}
		return returnString;
	}
	
	/**
	 * Verify a Web Element exists or not
	 * @param driver The WebDriver in use
	 * @param element The element to be verified
	 * @return boolean <br>
	 * Sample:<br>
	 * CommonMethods cm = new CommonMethods();
	 * cm.isUIExist(driver, Login_button);
	 */
	public boolean doesUIExist(WebElement element){
		boolean flag=false;
		try{
			flag=null!=element;
		}catch(NoSuchElementException e){
			logger.info("Element does NOT exsit...");
		}
		
		return flag;
	}
	
 
    /**
     * Take screenshot for current running script.
     * @param driver The WebDriver in use.
     */
	public static void takeScreenShot(Class className, WebDriver driver) {
		String time = dateString();
		String cn = className.getSimpleName();
		File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
		try {
			Files.copy(scrFile, new File("screenshot/" + cn + time + ".jpeg"));
			System.out.println("Screenshot '" + cn + time + ".jpeg' is taken." );
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	/**
	 * Get Roles/Reports collection
	 * @param filePath The file path + the file name.
	 * @param parValue The parameters for input collection name.
	 * @return String[] return get collection.<br>
	 * Sample:<br>
	 * 
	 */
	public static String[] getRunParameter(String filePath,String parValue) {
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

		DocumentBuilder builder = null;
		try {
			builder = factory.newDocumentBuilder();
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
		}

		Document doc = null;
		try {
			doc = builder.parse(new File(filePath));
		} catch (SAXException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		NodeList parNodes = doc.getElementsByTagName(parValue);
		int num = parNodes.getLength();
		String[] parClots = new String[num];

		for(int i=0;i<parNodes.getLength();i++){

		Element parElet = (Element)parNodes.item(i);

		parClots[i] = parElet.getAttribute("Value").toString();

		}
		
		return parClots;
	}

}